package main

// 目录引用： 使用 learn 下面的 sayHi 中的方法，使用 import "learn1/demo1"
//    其中，learn1 指向当前 go.mod 的模块，demo1 指向 demo1 目录
//    learn1/demo1 是绝对路径
import (
	"flag"
	"fmt"
	"learn1/demo1"
	"learn1/demo2"
	"learn1/demo3"
	"learn1/demo4"
	"learn1/demo7"
	"learn1/demo8"
	telnet "learn1/demoTelnet"
)

// 运行测试 go run demo6/main.go --demo=demo1
// main 程序启动的项目参数，决定跑哪些测试, demo 只是解析值的一个指针，需要 *demo 来取值
var demo = flag.String("demo", "all", "which demo")

func main() {
	fmt.Println("Hello, 123")

	flag.Parse()

	demoValue := *demo

	fmt.Println(demoValue)

	if demoValue == "telnet" {
		fmt.Println("telnet start")
		telnet.TestDemoTelnet()
		return
	}

	if demoValue == "all" || demoValue == "demo1" {
		fmt.Println("-------demo21----------")
		demo2.TestDemo21()
	}

	if demoValue == "all" || demoValue == "demo2" {
		/* 常量、基础测试  */
		fmt.Println("-------demo12----------")
		demo1.SaHi()
		demo1.TestDemo12()
		/* 数据类型 */
		fmt.Println("-------demo22----------")
		demo2.TestDemo22()
		fmt.Println("-------demo23----------")
		demo2.TestDemo23()
		// 结构体 struct: 通过 type 和 struct 定义
		fmt.Println("-------demo24----------")
		demo2.TestDemo24()
		fmt.Println("-------demo25----------")
		demo2.TestDemo25()
		fmt.Println("-------demo26----------")
		demo2.TestDemo26()
		fmt.Println("-------demo27----------")
		demo2.TestDemo27()
		fmt.Println("-------demo28----------")
		demo2.TestDemo28()
		fmt.Println("-------demo29----------")
		demo2.TestDemo29()
		// 结构体 struct 的使用，struct 指针的使用
		fmt.Println("-------demo210----------")
		demo2.TestDemo210()
		// 方法和接收器
		fmt.Println("-------demo211----------")
		demo2.TestDemo211()
		fmt.Println("-------demo212----------")
		demo2.TestDemo212()
		fmt.Println("-------demo213----------")
		demo2.TestDemo213()
		// 事件系统: 使用事件系统实现事件的响应和处理
		fmt.Println("-------demo214----------")
		demo2.TestDemo214()
		// 类型内嵌和结构体内嵌
		fmt.Println("-------demo215----------")
		demo2.TestDemo215()
		// 结构体内嵌模拟类的继承
		fmt.Println("-------demo216----------")
		demo2.TestDemo216()
		// 初始化内嵌结构体
		fmt.Println("-------demo217----------")
		demo2.TestDemo217()
		// 使用匿名结构体解析JSON数据
		fmt.Println("-------demo218----------")
		demo2.TestDemo218()
		// 垃圾回收和SetFinalizer -- GC
		fmt.Println("-------demo219----------")
		demo2.TestDemo219()
	}

	if demoValue == "all" || demoValue == "demo3" {
		/* 流程控制：循环、遍历、判断等 */
		fmt.Println("-------demo31----------")
		demo3.TestDemo31()
		fmt.Println("-------demo33----------")
		demo3.TestDemo33()
		fmt.Println("-------demo34----------")
		demo3.TestDemo34()
		fmt.Println("-------demo35----------")
		demo3.TestDemo35()
		fmt.Println("-------demo36----------")
		demo3.TestDemo36()
		// defer 语句的使用
		fmt.Println("-------demo37----------")
		demo3.TestDemo37()
		// panic 宕机
		fmt.Println("-------demo38----------")
		// demo3.TestDemo38()
		// panic 和 recover
		fmt.Println("-------demo39----------")
		demo3.TestDemo39()
		// time 包 耗时计算
		fmt.Println("-------demo310----------")
		demo3.TestDemo310()
		// 函数作为返回值，闭包
		fmt.Println("-------demo311----------")
		demo3.TestDemo311()
		// 通过内存缓存来提升性能
		fmt.Println("-------demo312----------")
		demo3.TestDemo312()
	}

	if demoValue == "all" || demoValue == "demo7" {
		/* 类型 type */
		fmt.Println("-------demo71-----------")
		demo7.TestDemo71()
		/* 接口 interface */
		fmt.Println("-------demo72-----------")
		demo7.TestDemo72()
	}

	if demoValue == "all" || demoValue == "demo4" {
		fmt.Println("-------demo41----------")
		demo4.TestDemo41()
		// 接口的定义和实现
		fmt.Println("-------demo42----------")
		demo4.TestDemo42()
		// 类型与接口的关系
		fmt.Println("-------demo43----------")
		demo4.TestDemo43()
		// 多个类型可以实现相同的接口
		fmt.Println("-------demo44----------")
		demo4.TestDemo44()
		// 类型断言
		fmt.Println("-------demo45----------")
		demo4.TestDemo45()
		// 实例： 日志写入
		fmt.Println("-------demo46----------")
		demo4.TestDemo46()
		// sort.Interface 排序的实现
		fmt.Println("-------demo47----------")
		demo4.TestDemo47()
		// 接口和类型之间的转换
		fmt.Println("-------demo49----------")
		demo4.TestDemo49()
		// 空接口类型（interface{}）
		fmt.Println("-------demo410----------")
		demo4.TestDemo410()
		// 使用空接口实现可以保存任意值的字典
		fmt.Println("-------demo411----------")
		demo4.TestDemo411()
		// type-switch 流程控制的语法
		fmt.Println("-------demo412----------")
		demo4.TestDemo412()
	}

	if demoValue == "all" || demoValue == "demo8" {
		/* demo8 并发测试 */
		// 简单的并发示例
		// fmt.Println("-------demo81----------")
		// demo8.TestDemo81()
		// 使用通道做并发同步
		fmt.Println("-------demo83----------")
		demo8.TestDemo83()
		// 使用 for range 遍历通道数据
		fmt.Println("-------demo84----------")
		demo8.TestDemo84()
		// 将 goroutine 和 channel 结合使用
		fmt.Println("-------demo85----------")
		demo8.TestDemo85()
		// 单向通道——通道中的单行道
		// fmt.Println("-------demo86----------")
		// demo8.TestDemo86()
		// 无缓冲的通道
		fmt.Println("-------demo87----------")
		demo8.TestDemo87()
		// 带缓冲的通道
		fmt.Println("-------demo88----------")
		// demo8.TestDemo88()
		// // channel超时机制
		fmt.Println("-------demo89----------")
		// demo8.TestDemo89()

		// 多路复用—— RPC 模拟远程过程调用
		fmt.Println("-------demo811----------")
		demo8.TestDemo811()
		// 使用通道响应计时器的事件
		fmt.Println("-------demo813----------")
		demo8.TestDemo813()
		// 定点计时, 使用 timer.NewTimer() 和 time.NewTicker()。
		fmt.Println("-------demo814----------")
		demo8.TestDemo814()
		// 原子访问（atomic包）
		fmt.Println("-------demo815----------")
		demo8.TestDemo815()
		// 互斥锁（sync.Mutex）和读写互斥锁（sync.RWMutex）
		fmt.Println("-------demo816----------")
		demo8.TestDemo816()
		// 等待组（sync.WaitGroup）
		fmt.Println("-------demo817----------")
		demo8.TestDemo817()
	}
}
